﻿using AutoMapper;
using Urs.Admin.Models.Banners;
using Urs.Admin.Models.Common;
using Urs.Admin.Models.Common;
using Urs.Admin.Models.Coupons;
using Urs.Admin.Models.Directory;
using Urs.Admin.Models.ExternalAuthentication;
using Urs.Admin.Models.Logging;
using Urs.Admin.Models.Payments;
using Urs.Admin.Models.Settings;
using Urs.Admin.Models.Shipping;
using Urs.Admin.Models.Stores;
using Urs.Admin.Models.Topics;
using Urs.Admin.Models.Users;
using Urs.Core.Infrastructure.Mapper;
using Urs.Core.Plugins;
using Urs.Data.Domain.Banners;
using Urs.Data.Domain.Common;
using Urs.Data.Domain.Configuration;
using Urs.Data.Domain.Coupons;
using Urs.Data.Domain.Directory;
using Urs.Data.Domain.Logging;
using Urs.Data.Domain.Shipping;
using Urs.Data.Domain.Stores;
using Urs.Data.Domain.Topics;
using Urs.Data.Domain.Users;
using Urs.Services.Authentication.External;
using Urs.Services.Configuration;
using Urs.Services.Payments;
using Urs.Services.Shipping;

namespace Urs.Admin.Infrastructure
{
    public class AdminMapperConfiguration : Profile, IOrderedMapperProfile
    {
        public AdminMapperConfiguration()
        {
            //address
            CreateMap<Address, AddressModel>()
                .ForMember(dest => dest.AddressHtml, mo => mo.Ignore())
                .ForMember(dest => dest.NameEnabled, mo => mo.Ignore())
                .ForMember(dest => dest.NameRequired, mo => mo.Ignore())
                .ForMember(dest => dest.CompanyEnabled, mo => mo.Ignore())
                .ForMember(dest => dest.CompanyRequired, mo => mo.Ignore())
                .ForMember(dest => dest.ProvincesEnabled, mo => mo.Ignore())
                .ForMember(dest => dest.StreetAddressEnabled, mo => mo.Ignore())
                .ForMember(dest => dest.StreetAddressRequired, mo => mo.Ignore())
                .ForMember(dest => dest.StreetAddress2Enabled, mo => mo.Ignore())
                .ForMember(dest => dest.StreetAddress2Required, mo => mo.Ignore())
                .ForMember(dest => dest.ZipPostalCodeEnabled, mo => mo.Ignore())
                .ForMember(dest => dest.ZipPostalCodeRequired, mo => mo.Ignore())
                .ForMember(dest => dest.PhoneEnabled, mo => mo.Ignore())
                .ForMember(dest => dest.PhoneRequired, mo => mo.Ignore())
                .ForMember(dest => dest.FaxEnabled, mo => mo.Ignore())
                .ForMember(dest => dest.FaxRequired, mo => mo.Ignore());
            CreateMap<AddressModel, Address>()
                .ForMember(dest => dest.CreateTime, mo => mo.Ignore());

            //topcis
            CreateMap<Topic, TopicModel>()
                .ForMember(dest => dest.Url, mo => mo.Ignore());
            CreateMap<TopicModel, Topic>();
            //category
            CreateMap<Category, CategoryModel>()
                .ForMember(dest => dest.Breadcrumb, mo => mo.Ignore())
                .ForMember(dest => dest.ParentCategories, mo => mo.Ignore());
            CreateMap<CategoryModel, Category>()
                .ForMember(dest => dest.CreateTime, mo => mo.Ignore())
                .ForMember(dest => dest.UpdateTime, mo => mo.Ignore())
                .ForMember(dest => dest.Deleted, mo => mo.Ignore());

            //coupons
            CreateMap<Coupon, CouponModel>();
            CreateMap<CouponModel, Coupon>();

            //brand
            CreateMap<Brand, BrandModel>()
                .ForMember(dest => dest.AvailableUserRoles, mo => mo.Ignore())
                .ForMember(dest => dest.SelectedUserRoleIds, mo => mo.Ignore());
            CreateMap<BrandModel, Brand>()
                .ForMember(dest => dest.CreateTime, mo => mo.Ignore())
                .ForMember(dest => dest.UpdateTime, mo => mo.Ignore())
                .ForMember(dest => dest.Deleted, mo => mo.Ignore());

            //banner
            CreateMap<Banner, BannerModel>();
            CreateMap<BannerModel, Banner>();
            CreateMap<BannerItem, BannerItemModel>();
            CreateMap<BannerItemModel, BannerItem>();

            CreateMap<Goods, GoodsModel>()
                .ForMember(dest => dest.GoodsTags, mo => mo.Ignore())
                .ForMember(dest => dest.PictureThumbnailUrl, mo => mo.Ignore())
                .ForMember(dest => dest.AvailableCategories, mo => mo.Ignore())
                .ForMember(dest => dest.AvailableBrands, mo => mo.Ignore())
                .ForMember(dest => dest.BaseDimensionIn, mo => mo.Ignore())
                .ForMember(dest => dest.BaseWeightIn, mo => mo.Ignore());
            CreateMap<GoodsModel, Goods>()
                .ForMember(dest => dest.GoodsTags, mo => mo.Ignore())
                .ForMember(dest => dest.CreateTime, mo => mo.Ignore())
                .ForMember(dest => dest.UpdateTime, mo => mo.Ignore())
                .ForMember(dest => dest.Deleted, mo => mo.Ignore())
                .ForMember(dest => dest.ApprovedRatingSum, mo => mo.Ignore())
                .ForMember(dest => dest.ApprovedTotalReviews, mo => mo.Ignore())
                .ForMember(dest => dest.GoodsSpecCombinations, mo => mo.Ignore());

            //logs
            CreateMap<Log, LogModel>()
                .ForMember(dest => dest.CreateTime, mo => mo.Ignore());
            CreateMap<LogModel, Log>()
                .ForMember(dest => dest.CreateTime, mo => mo.Ignore())
                .ForMember(dest => dest.LogLevelId, mo => mo.Ignore())
                .ForMember(dest => dest.User, mo => mo.Ignore());
            //ActivityLogType
            CreateMap<ActivityLogTypeModel, ActivityLogType>()
                .ForMember(dest => dest.SystemKeyword, mo => mo.Ignore());
            CreateMap<ActivityLogType, ActivityLogTypeModel>();
            CreateMap<ActivityLog, ActivityLogModel>()
                .ForMember(dest => dest.ActivityLogTypeName, mo => mo.Ignore())
                .ForMember(dest => dest.UserEmail, mo => mo.Ignore())
                .ForMember(dest => dest.CreateTime, mo => mo.Ignore());

            //measure weights
            CreateMap<MeasureWeight, MeasureWeightModel>()
                .ForMember(dest => dest.IsPrimaryWeight, mo => mo.Ignore());
            CreateMap<MeasureWeightModel, MeasureWeight>();
            //measure dimensions
            CreateMap<MeasureDimension, MeasureDimensionModel>()
                .ForMember(dest => dest.IsPrimaryDimension, mo => mo.Ignore());
            CreateMap<MeasureDimensionModel, MeasureDimension>();

            //shipping methods
            CreateMap<ShippingMethod, ShippingMethodModel>();
            CreateMap<ShippingMethodModel, ShippingMethod>();
            //shipping rate computation methods
            CreateMap<IShippingRateMethod, ShippingRateMethodModel>()
                .ForMember(dest => dest.FriendlyName, mo => mo.MapFrom(src => src.PluginDescriptor.FriendlyName))
                .ForMember(dest => dest.SystemName, mo => mo.MapFrom(src => src.PluginDescriptor.SystemName))
                .ForMember(dest => dest.DisplayOrder, mo => mo.MapFrom(src => src.PluginDescriptor.DisplayOrder))
                .ForMember(dest => dest.IsActive, mo => mo.Ignore())
                .ForMember(dest => dest.LogoUrl, mo => mo.Ignore())
                .ForMember(dest => dest.ConfigurationActionName, mo => mo.Ignore())
                .ForMember(dest => dest.ConfigurationControllerName, mo => mo.Ignore())
                .ForMember(dest => dest.ConfigurationRouteValues, mo => mo.Ignore());
            //payment methods
            CreateMap<IPaymentMethod, PaymentMethodModel>()
                .ForMember(dest => dest.FriendlyName, mo => mo.MapFrom(src => src.PluginDescriptor.FriendlyName))
                .ForMember(dest => dest.SystemName, mo => mo.MapFrom(src => src.PluginDescriptor.SystemName))
                .ForMember(dest => dest.DisplayOrder, mo => mo.MapFrom(src => src.PluginDescriptor.DisplayOrder))
                .ForMember(dest => dest.IsActive, mo => mo.Ignore())
                .ForMember(dest => dest.LogoUrl, mo => mo.Ignore())
                .ForMember(dest => dest.ConfigurationActionName, mo => mo.Ignore())
                .ForMember(dest => dest.ConfigurationControllerName, mo => mo.Ignore())
                .ForMember(dest => dest.ConfigurationRouteValues, mo => mo.Ignore());
            //external authentication methods
            CreateMap<IExternalAuthenticationMethod, AuthenticationMethodModel>()
                .ForMember(dest => dest.FriendlyName, mo => mo.MapFrom(src => src.PluginDescriptor.FriendlyName))
                .ForMember(dest => dest.SystemName, mo => mo.MapFrom(src => src.PluginDescriptor.SystemName))
                .ForMember(dest => dest.DisplayOrder, mo => mo.MapFrom(src => src.PluginDescriptor.DisplayOrder))
                .ForMember(dest => dest.IsActive, mo => mo.Ignore())
                .ForMember(dest => dest.ConfigurationActionName, mo => mo.Ignore())
                .ForMember(dest => dest.ConfigurationControllerName, mo => mo.Ignore())
                .ForMember(dest => dest.ConfigurationRouteValues, mo => mo.Ignore());
            //widgets
            CreateMap<IWidgetPlugin, WidgetModel>()
                .ForMember(dest => dest.FriendlyName, mo => mo.MapFrom(src => src.PluginDescriptor.FriendlyName))
                .ForMember(dest => dest.SystemName, mo => mo.MapFrom(src => src.PluginDescriptor.SystemName))
                .ForMember(dest => dest.DisplayOrder, mo => mo.MapFrom(src => src.PluginDescriptor.DisplayOrder))
                .ForMember(dest => dest.IsActive, mo => mo.Ignore())
                .ForMember(dest => dest.ConfigurationActionName, mo => mo.Ignore())
                .ForMember(dest => dest.ConfigurationControllerName, mo => mo.Ignore())
                .ForMember(dest => dest.ConfigurationRouteValues, mo => mo.Ignore());
            //plugins
            CreateMap<PluginDescriptor, PluginModel>()
                .ForMember(dest => dest.ConfigurationUrl, mo => mo.Ignore())
                .ForMember(dest => dest.CanChangeEnabled, mo => mo.Ignore())
                .ForMember(dest => dest.LogoUrl, mo => mo.Ignore())
                .ForMember(dest => dest.IsEnabled, mo => mo.Ignore());
            
            //user roles
            CreateMap<UserRole, UserRoleModel>();
            CreateMap<UserRoleModel, UserRole>();

            //goods attributes
            CreateMap<GoodsSpec, GoodsSpecModel>();
            CreateMap<GoodsSpecModel, GoodsSpec>();
            //specification attributes
            CreateMap<GoodsParameterGroup, GoodsParameterGroupModel>();
            CreateMap<GoodsParameterGroupModel, GoodsParameterGroup>();
            CreateMap<GoodsParameter, GoodsParameterModel>();
            CreateMap<GoodsParameterModel, GoodsParameter>()
                .ForMember(dest => dest.GoodsParameterOptions, mo => mo.Ignore());
            CreateMap<GoodsParameterOption, GoodsParameterOptionModel>();
            CreateMap<GoodsParameterOptionModel, GoodsParameterOption>()
                .ForMember(dest => dest.Mapping, mo => mo.Ignore())
                .ForMember(dest => dest.GoodsParameters, mo => mo.Ignore());

            //Settings

            CreateMap<ShippingSettings, ShippingSettingsModel>()
                .ForMember(dest => dest.ShippingOriginAddress, mo => mo.Ignore());
            CreateMap<ShippingSettingsModel, ShippingSettings>()
                .ForMember(dest => dest.ActiveShippingRateComputationMethodSystemNames, mo => mo.Ignore())
                .ForMember(dest => dest.ActiveShippingExpressNames, mo => mo.Ignore())
                .ForMember(dest => dest.ReturnValidOptionsIfThereAreAny, mo => mo.Ignore());
            CreateMap<StoreSettings, StoreSettingsModel>();
            CreateMap<StoreSettingsModel, StoreSettings>();
            CreateMap<RewardPointsSettings, PointsSettingsModel>()
                .ForMember(dest => dest.PrimaryStoreCurrencyCode, mo => mo.Ignore());
            CreateMap<PointsSettingsModel, RewardPointsSettings>();
            CreateMap<OrderSettings, OrderSettingsModel>()
                .ForMember(dest => dest.AfterSalesReasonsParsed, mo => mo.Ignore())
                .ForMember(dest => dest.AfterSalesActionsParsed, mo => mo.Ignore())
                .ForMember(dest => dest.PrimaryStoreCurrencyCode, mo => mo.Ignore())
                .ForMember(dest => dest.OrderIdent, mo => mo.Ignore());
            CreateMap<OrderSettingsModel, OrderSettings>()
                .ForMember(dest => dest.AfterSalesReasons, mo => mo.Ignore())
                .ForMember(dest => dest.AfterSalesActions, mo => mo.Ignore())
                .ForMember(dest => dest.MinimumOrderPlacementInterval, mo => mo.Ignore());
            CreateMap<ShoppingCartSettings, ShoppingCartSettingsModel>();
            CreateMap<ShoppingCartSettingsModel, ShoppingCartSettings>()
                .ForMember(dest => dest.RoundPricesDuringCalculation, mo => mo.Ignore());
            CreateMap<MediaSettings, MediaSettingsModel>()
                .ForMember(dest => dest.PicturesStoredIntoDatabase, mo => mo.Ignore());
            CreateMap<MediaSettingsModel, MediaSettings>()
                .ForMember(dest => dest.DefaultPictureZoomEnabled, mo => mo.Ignore())
                .ForMember(dest => dest.DefaultImageQuality, mo => mo.Ignore())
                .ForMember(dest => dest.AutoCompleteSearchThumbPictureSize, mo => mo.Ignore());
            CreateMap<UserSettings, UserSettingsModel.UserInfoSettingsModel>();
            CreateMap<UserSettingsModel.UserInfoSettingsModel, UserSettings>()
                .ForMember(dest => dest.HashedPasswordFormat, mo => mo.Ignore())
                .ForMember(dest => dest.PasswordMinLength, mo => mo.Ignore())
                .ForMember(dest => dest.AvatarMaximumSizeBytes, mo => mo.Ignore())
                .ForMember(dest => dest.OnlineUserMinutes, mo => mo.Ignore());
            CreateMap<AddressSettings, UserSettingsModel.AddressSettingsModel>();
            CreateMap<UserSettingsModel.AddressSettingsModel, AddressSettings>();
            CreateMap<TemplateSettings, TemplateSettingsModel>();
            CreateMap<TemplateSettingsModel, TemplateSettings>();


            CreateMap<Shop, ShopModel>();
            CreateMap<ShopModel, Shop>()
                .ForMember(dest => dest.CreateTime, mo => mo.Ignore());
        }

        public int Order
        {
            get { return 0; }
        }
    }
}